home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 4 / Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso / Development / Source / Dialectic 1.2.source Folder / Dialectic ƒ / Shell ƒ / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-26  |  10.3 KB  |  329 lines  |  [TEXT/KAHL]

  1. /**********************************************************************\
  2.  
  3. File:        main.c
  4.  
  5. Purpose:    This module handles the event loop and event dispatching.
  6.  
  7. \**********************************************************************/
  8.  
  9. #include "graphics.h"
  10. #include "main.h"
  11. #include "apple events.h"
  12. #include "integrity.h"
  13. #include "about.h"
  14. #include "help.h"
  15. #include "menus.h"
  16. #include "prefs.h"
  17. #include "environment.h"
  18. #include "progress.h"
  19. #include "error.h"
  20. #include "dialectic.h"
  21. #include "program globals.h"
  22.  
  23. void main(void)
  24. {
  25.     Boolean            programIntegrityVerified;
  26.     Boolean            programIntegritySet;
  27.     
  28.     /* do integrity check before anything else; see integrity.c for details */
  29.     programIntegrityVerified=DoIntegrityCheck(&programIntegritySet);
  30.     
  31.     /* standard program initialization stuff */
  32.     MaxApplZone();    
  33.     InitGraf(&thePort);
  34.     InitFonts();
  35.     FlushEvents(everyEvent, 0);
  36.     InitWindows();
  37.     InitMenus();
  38.     TEInit();
  39.     InitDialogs(0L);
  40.     InitCursor();
  41.     GetDateTime(&randSeed);
  42.     
  43.     if (!InitTheEnvironment())            /* gestalt checks and variable initialization */
  44.         HandleError(kSystemTooOld, TRUE);        /* less than system 4.1 */
  45.     
  46.     if (!programIntegrityVerified)    /* integrity check failed */
  47.         HandleError(kProgramIntegrityNotVerified, TRUE);
  48.     
  49.     if (programIntegritySet)    /* integrity check freshly installed */
  50.         HandleError(kProgramIntegritySet, FALSE);
  51.     
  52.     if (!InitTheMenus())        /* get menus from .rsrc and draw menu bar */
  53.         HandleError(kProgramIntegrityNotVerified, TRUE);
  54.         
  55.     if (!InitTheGraphics())        /* initialize offscreen gworlds/bitmaps, etc */
  56.         HandleError(kNoMemoryAndQuitting, TRUE);
  57.     
  58.     PrefsError(PreferencesInit());    /* get prefs (create if necessary) */
  59.     
  60.     InitTheProgram();                /* program-specific initialization */
  61.     
  62.     EventLoop();                    /* where it all happens (see below) */
  63.     
  64.     ShutDownEnvironment();            /* where it all ends (see below) */
  65.     
  66.     ExitToShell();
  67. }
  68.  
  69. void EventLoop(void)
  70. {
  71.     EventRecord        theEvent;
  72.     int                i;
  73.     
  74.     while (!gDone)    /* gDone set by choosing "Quit" menu item or by "quit" apple event */
  75.     {
  76.         SetCursor(&arrow);        /* should set once every time through event loop */
  77.         HiliteMenu(0);            /* normalize menubar */
  78.         
  79.         gFrontWindowIsOurs=FALSE;
  80.         if (FrontWindow()!=0L)    /* if there's a front window, see if it's one of ours */
  81.         {
  82.             for (i=0; ((i<NUM_WINDOWS) && (!gFrontWindowIsOurs)); i++)
  83.             {
  84.                 if (FrontWindow()==gTheWindow[i])    /* found one of ours, so SetPort */
  85.                 {
  86.                     SetPort(gTheWindow[i]);
  87.                     gFrontWindowIsOurs=TRUE;
  88.                 }
  89.             }
  90.         }
  91.             
  92.         /* get an event from the queue */
  93.         GetTheEvent(&theEvent, gIsInBackground ? gBackgroundWaitTime : gForegroundWaitTime);
  94.         
  95.         DispatchEvents(theEvent);    /* handle the event we just got */
  96.     }
  97. }
  98.  
  99. void GetTheEvent(EventRecord *theEvent, int waitTime)
  100. {
  101.     if (gWaitNextEventAvailable)
  102.         WaitNextEvent(everyEvent, theEvent, waitTime, 0L);
  103.     else
  104.     {
  105.         GetNextEvent(everyEvent, theEvent);
  106.         SystemTask();
  107.     }
  108. }
  109.  
  110. void DispatchEvents(EventRecord theEvent)
  111. {
  112.     int                i;
  113.     Point            thisPoint;
  114.     int                index;
  115.     unsigned long    dummy;
  116.     WindowPtr        theWindow;
  117.     Boolean            thisWindowIsOurs;
  118.     ExtendedWindowDataHandle
  119.                     theData;
  120.     
  121.     thisWindowIsOurs=FALSE;
  122.     /* for update/activate events, see if the window in question is one of ours */
  123.     if ((theEvent.what==activateEvt) || (theEvent.what==updateEvt))
  124.     {
  125.         for (i=0; ((i<NUM_WINDOWS) && (!thisWindowIsOurs)); i++)
  126.             thisWindowIsOurs=((WindowPtr)theEvent.message==gTheWindow[i]);
  127.     }
  128.  
  129.     if (thisWindowIsOurs)    /* for activate/update events, get window data structure */
  130.     {
  131.         theData=(WindowDataHandle)GetWRefCon((WindowPtr)theEvent.message);
  132.         index=(**theData).windowIndex;
  133.     }
  134.     else if (gFrontWindowIsOurs)    /* if front window is ours, get window data struct */
  135.     {
  136.         theData=(WindowDataHandle)GetWRefCon(FrontWindow());
  137.         index=(**theData).windowIndex;
  138.     }
  139.     else index=-1;
  140.     
  141.     switch (theEvent.what)
  142.     {
  143.         case nullEvent:    /* ain't nuthin' happenin' */
  144.             if (gFrontWindowIsOurs)        /* give control to window dispatch to handle null */
  145.                 ((**theData).dispatchProc)(theData, kNull, 0L);
  146.             break;
  147.         case mouseDown:    /* mouse button pressed */
  148.             HandleMouseDown(theEvent);    /* see below for mousedown handling */
  149.             break;
  150.         case keyDown:    /* key pressed */
  151.         case autoKey:    /* key help down */
  152.             if (theEvent.modifiers & cmdKey)    /* handle as command-key equivalent */
  153.             {
  154.                 AdjustMenus();    /* just to be safe */
  155.                 /* get the menu ID + item and handle it as a menu choice */
  156.                 HandleMenu(MenuKey((char)(theEvent.message & charCodeMask)));
  157.             }
  158.             else if (gFrontWindowIsOurs)    /* --> window's dispatch for keydown */
  159.                 ((**theData).dispatchProc)(theData, kKeydown, theEvent.message);
  160.             break;
  161.         case diskEvt:    /* disk insert */
  162.             if (HiWord(theEvent.message)!=noErr)    /* bad disk inserted */
  163.             {
  164.                 DILoad();    /* load disk initialization package */
  165.                 SetPt(&thisPoint, 120, 120);
  166.                 DIBadMount(thisPoint, theEvent.message);    /* give format? dialog */
  167.                 DIUnload();    /* unload 'cuz we certainly don't need it */
  168.             }
  169.             break;
  170.         case updateEvt:    /* window update */
  171.             theWindow=(WindowPtr)theEvent.message;    /* which window? */
  172.             
  173.             BeginUpdate(theWindow);        /* means: "OK, we're dealing with this now" */
  174.             
  175.             if (thisWindowIsOurs)        /* one of ours?  see graphics.c */
  176.                 UpdateTheWindow(theData);
  177.             /* if not, could be our progress bar */
  178.             else if ((theWindow!=0L) && (theWindow==gProgressDlog))
  179.                 UpdateDialog(theWindow, theWindow->visRgn);
  180.             
  181.             EndUpdate(theWindow);        /* means: "OK, we're done updating now" */
  182.             break;
  183.         case activateEvt:    /* window activate or deactivate */
  184.             if (thisWindowIsOurs)        /* one of ours?  send message to window dispatch */
  185.                 ((**theData).dispatchProc)(theData,
  186.                     ((theEvent.modifiers&activeFlag)!=0) ? kActivate : kDeactivate, 0L);
  187.             break;
  188.         case osEvt:            /* suspend or resume program execution (switch in/out) */
  189.             if (((theEvent.message>>24)&0x0FF)==suspendResumeMessage)
  190.             {
  191.                 /* keep track of whether we're in the background or foreground */
  192.                 gIsInBackground=((theEvent.message&resumeFlag)==0);
  193.                 
  194.                 if (gFrontWindowIsOurs)        /* send activate/deactivate to front window */
  195.                     ((**theData).dispatchProc)(theData, gIsInBackground ?
  196.                         kDeactivate : kActivate, 0L);
  197.                 
  198.                 for (i=0; i<NUM_WINDOWS; i++)    /* send suspend/resume to all our */
  199.                     if (gTheWindow[i]!=0L)        /* windows that currently exist */
  200.                         ((**(gTheWindowData[i])).dispatchProc)(gTheWindowData[i],
  201.                             gIsInBackground ? kSuspend : kResume, 0L);
  202.                 
  203.                 /* if we just came into the foreground and we have a pending error,
  204.                    now's the time to display it */
  205.                 if ((!gIsInBackground) && (gPendingResultCode!=allsWell))
  206.                 {
  207.                     if (gHasNotificationManager)
  208.                         NMRemove(&gMyNotification);        /* remove notification request */
  209.                     HandleError(gPendingResultCode, FALSE);    /* display alert, see error.c */
  210.                     gPendingResultCode=allsWell;        /* ...now it is */
  211.                 }
  212.             }
  213.             break;
  214.         case kHighLevelEvent:    /* apple event */
  215.             if (gHasAppleEvents)
  216.                 AEProcessAppleEvent(&theEvent);        /* see apple events.c */
  217.             break;
  218.     }
  219. }
  220.  
  221. void HandleMouseDown(EventRecord theEvent)
  222. {
  223.     WindowPtr            theWindow;
  224.     int                    windowCode;
  225.     long                windSize;
  226.     GrafPtr                oldPort;
  227.     int                    i;
  228.     Rect                sizeRect;
  229.     Boolean                gotone;
  230.     int                    index;
  231.     unsigned long        dummy;
  232.     Point                theLocalPoint;
  233.     Boolean                thisWindowIsOurs;
  234.     ExtendedWindowDataHandle    theData;
  235.     
  236.     windowCode=FindWindow(theEvent.where, &theWindow);    /* which window? */
  237.  
  238.     thisWindowIsOurs=FALSE;
  239.     /* find out if the target window was one of ours */
  240.     if (theWindow!=0L)
  241.         for (index=0; ((index<NUM_WINDOWS) && (!thisWindowIsOurs)); index++)
  242.             thisWindowIsOurs=(theWindow==gTheWindow[index]);
  243.  
  244.     if (thisWindowIsOurs)    /* if target window is one of ours, get window data struct */
  245.     {
  246.         theData=(WindowDataHandle)GetWRefCon(theWindow);
  247.         index=(**theData).windowIndex;
  248.     }
  249.     else index=-1;
  250.     
  251.     switch (windowCode)
  252.     {
  253.         case inMenuBar:        /* in menu bar; let system take over */
  254.             AdjustMenus();
  255.             HandleMenu(MenuSelect(theEvent.where));
  256.             break;
  257.         case inContent:        /* in window content */
  258.             if (FrontWindow() != theWindow)        /* maybe switch to different window */
  259.             {
  260.                 if (FrontWindow()==gProgressDlog)    /* but not if progress bar is up */
  261.                     SysBeep(7);
  262.                 else SelectWindow(theWindow);
  263.             }
  264.             else if (gFrontWindowIsOurs)    /* inform window dispatch of mousedown */
  265.             {
  266.                 GetMouse(&theLocalPoint);    /* in window's local coordinates */
  267.                 dummy=theLocalPoint.h;        /* all this fiddling is so we can pass */
  268.                 dummy=dummy<<16;            /* the point (two integers) to the */
  269.                 dummy+=theLocalPoint.v;        /* dispatch procedure in an unsigned long */
  270.                 ((**theData).dispatchProc)(theData, kMousedown, dummy);    /* go for it */
  271.             }
  272.             break;
  273.         case inSysWindow:    /* in system window (desk accessory) */
  274.             SystemClick(&theEvent, theWindow);    /* let the system deal with it */
  275.             break;
  276.         case inDrag:        /* in drag _region_, that is */
  277.             /* the accepted way to draw a window */
  278.             DragWindow(theWindow, theEvent.where, &((**GetGrayRgn()).rgnBBox));
  279.             if (thisWindowIsOurs)    /* update window bounds in window data struct */
  280.                 (**theData).windowBounds=(*(((WindowPeek)gTheWindow[index])->contRgn))->rgnBBox;
  281.             break;
  282.         case inGoAway:        /* close box */
  283.             /* the accepted way to track a close box attempt */
  284.             if (TrackGoAway(theWindow, theEvent.where))
  285.                 DoTheCloseThing(theWindow);        /* see menus.c */
  286.             break;
  287.         case inGrow:        /* grow box */
  288.             /* the accepted way to grow a window */
  289.             sizeRect = screenBits.bounds;
  290.             OffsetRect(&sizeRect, sizeRect.left, sizeRect.top);
  291.             
  292.             windSize = GrowWindow(theWindow, theEvent.where, &sizeRect);
  293.             if (windSize != 0)
  294.             {
  295.                 GetPort(&oldPort);
  296.                 SetPort(theWindow);
  297.                 EraseRect(&theWindow->portRect);
  298.                 SizeWindow(theWindow, LoWord(windSize), HiWord(windSize), TRUE);
  299.                 InvalRect(&theWindow->portRect);
  300.                 SetPort(oldPort);
  301.             }
  302.             
  303.             if (thisWindowIsOurs)    /* update window bounds in window data struct */
  304.                 (**theData).windowBounds=(*(((WindowPeek)gTheWindow[index])->contRgn))->rgnBBox;
  305.             break;
  306.         case inZoomIn:        /* zoom box */
  307.         case inZoomOut:
  308.             /* the accepted way to track a zoom attempt */
  309.             if (TrackBox(theWindow, theEvent.where, windowCode))
  310.             {
  311.                 GetPort(&oldPort);
  312.                 SetPort(theWindow);
  313.                 ZoomWindow(theWindow, windowCode, FALSE);
  314.                 InvalRect(&theWindow->portRect);
  315.                 SetPort(oldPort);
  316.             }
  317.             
  318.             if (thisWindowIsOurs)    /* update window bounds in window data struct */
  319.                 (**theData).windowBounds=(*(((WindowPeek)gTheWindow[index])->contRgn))->rgnBBox;
  320.             break;
  321.     }
  322. }
  323.  
  324. void ShutDownEnvironment(void)
  325. {
  326.     ShutDownTheProgram();        /* program-specific cleanup */
  327.     ShutDownTheGraphics();        /* shell-specific clean-up */
  328. }
  329.